package qc.module.demo.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.DateUtil;
import qc.module.demo.dto.student.StudentAddDto;
import qc.module.demo.dto.student.StudentDto;
import qc.module.demo.dto.student.StudentQueryConditionDto;
import qc.module.demo.dto.student.StudentScoreDto;
import qc.module.demo.entity.Student;
import qc.module.demo.entity.Score;
import qc.module.demo.entity.Course;
import qc.module.demo.mapper.StudentMapper;
import qc.module.demo.repository.StudentRepository;
import qc.module.demo.repository.ScoreRepository;
import qc.module.demo.repository.CourseRepository;

import java.util.Date;
import java.util.List;
import java.util.ArrayList;

/**
 * StudentService
 */
@Service
public class StudentService {
    private StudentRepository repository;
    private ScoreRepository scoreRepository;
    private CourseRepository courseRepository;

    @Autowired
    public void setStudentRepository(StudentRepository repository) {
        this.repository = repository;
    }
    
    @Autowired
    public void setScoreRepository(ScoreRepository scoreRepository) {
        this.scoreRepository = scoreRepository;
    }
    
    @Autowired
    public void setCourseRepository(CourseRepository courseRepository) {
        this.courseRepository = courseRepository;
    }

    /**
     * 根据条件查询学生信息
     *
     * @param condition 查询条件
     * @return 学生信息集合
     */
    public List<StudentDto> query(StudentQueryConditionDto condition) {
        LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
        
        // 添加班级编码查询条件
        if (condition.getClassNo() != null && !condition.getClassNo().isEmpty()) {
            wrapper.eq(Student::getClasscode, condition.getClassNo());
        }
        
        // 添加关键字查询条件
        if (condition.getKeywords() != null && !condition.getKeywords().isEmpty()) {
            wrapper.and(w -> w.like(Student::getName, condition.getKeywords())
                    .or()
                    .like(Student::getNo, condition.getKeywords())
                    .or()
                    .like(Student::getPhone, condition.getKeywords())
                    .or()
                    .like(Student::getHomeaddress, condition.getKeywords()));
        }
        
        // 添加入学时间查询条件
        if (condition.getTm() != null && !condition.getTm().isEmpty()) {
            wrapper.likeRight(Student::getInschoolday, condition.getTm());
        }

        //排序
        wrapper.orderByAsc(Student::getNo);

        //查询数据
        List<Student> students = repository.selectList(wrapper);

        if (students != null && !students.isEmpty())
            return StudentMapper.MAPPER.toDtoList(students);

        return null;
    }
    
    /**
     * 根据学号获取学生信息
     *
     * @param id 学号
     * @return 学生信息
     */
    public StudentDto get(String id) {
        if (id == null || id.isEmpty()) {
            return null;
        }
        
        Student student = repository.selectById(id);
        if (student != null) {
            return StudentMapper.MAPPER.toDto(student);
        }
        
        return null;
    }
    
    /**
     * 添加学生信息
     *
     * @param studentAddDto 学生信息
     * @return 添加结果
     */
    public String add(StudentAddDto studentAddDto) {
        // 参数校验
        if (studentAddDto == null)
            return QCUnifyReturnValue.Warn("对象不能为空");

        if (StringUtils.isBlank(studentAddDto.getNo()))
            return QCUnifyReturnValue.Warn("学号不能为空");

        if (StringUtils.isBlank(studentAddDto.getName()))
            return QCUnifyReturnValue.Warn("姓名不能为空");

        if (StringUtils.isBlank(studentAddDto.getClassCode()))
            return QCUnifyReturnValue.Warn("班级编码不能为空");

        if (StringUtils.isBlank(studentAddDto.getBirthday()))
            return QCUnifyReturnValue.Warn("出生日期不能为空");

        if (StringUtils.isBlank(studentAddDto.getInSchoolDay()))
            return QCUnifyReturnValue.Warn("入学日期不能为空");

        // 检查学号是否已存在
        if (repository.selectById(studentAddDto.getNo()) != null) {
            return QCUnifyReturnValue.Warn("学号已存在");
        }

        // 将DTO转换为实体
        Student student = StudentMapper.MAPPER.toEntity(studentAddDto);

        // 手动设置主键
        student.setNo(studentAddDto.getNo());

        // 处理日期转换
        if (!StringUtils.isBlank(studentAddDto.getBirthday())) {
            Date birthday = DateUtil.parseDate(studentAddDto.getBirthday());
            student.setBirthday(birthday);
        }

        if (!StringUtils.isBlank(studentAddDto.getInSchoolDay())) {
            Date inSchoolDay = DateUtil.parseDate(studentAddDto.getInSchoolDay());
            student.setInschoolday(inSchoolDay);
        }

        // 设置其他字段
        student.setPhone(studentAddDto.getPhone());
        student.setHomeaddress(studentAddDto.getHomeAddress());
        student.setClasscode(studentAddDto.getClassCode());

        // 保存到数据库
        int result = repository.insert(student);
        if (result > 0) {
            return QCUnifyReturnValue.Success(); // 成功返回null
        } else {
            return QCUnifyReturnValue.Warn("新增失败");
        }
    } 

    /**
     * 修改学生信息
     *
     * @param studentDto 学生信息
     * @return 修改结果
     */
    public String update(StudentDto studentDto) {
        // 参数校验
        if (studentDto == null)
            return QCUnifyReturnValue.Warn("对象不能为空");
        
        if (StringUtils.isBlank(studentDto.getNo()))
            return QCUnifyReturnValue.Warn("学号不能为空");

        // 检查学号是否存在
        if (repository.selectById(studentDto.getNo()) == null) {
            return QCUnifyReturnValue.Warn("学号不存在");
        }

        // 将DTO转换为实体
        Student student = StudentMapper.MAPPER.toEntity(studentDto);
        // 确保主键正确设置
        student.setNo(studentDto.getNo());

        // 更新数据库
        int result = repository.updateById(student);
        if (result > 0) {
            return QCUnifyReturnValue.Success();
        } else {
            return QCUnifyReturnValue.Warn("更新失败");
        }
    }

    
    /**
     * 删除学生信息
     *
     * @param id 学号
     * @return 删除结果
     */
    public String delete(String id) {
        //检查参数是否为空
        if (id == null || id.isEmpty()){
            return QCUnifyReturnValue.Warn("学号不能为空");
        }
        
        //检查学号是否存在
        if (repository.selectById(id) == null) {
            return QCUnifyReturnValue.Warn("学号不存在");
        }
        
        //删除数据
        int result = repository.deleteById(id);
        if (result > 0) {
            return QCUnifyReturnValue.Success();
        }else {
            return QCUnifyReturnValue.Warn("删除失败");
        }
    }
    
    /**
     * 获取学生成绩信息
     *
     * @param studentNo 学号
     * @return 学生成绩列表
     */
    public List<StudentScoreDto> getScores(String studentNo) {
        // 构造查询条件
        LambdaQueryWrapper<Score> scoreWrapper = new LambdaQueryWrapper<>();
        if (studentNo != null && !studentNo.isEmpty()) {
            scoreWrapper.eq(Score::getStudentno, studentNo);
        }
        
        // 查询成绩信息
        List<Score> scores = scoreRepository.selectList(scoreWrapper);
        
        // 转换为DTO并填充课程信息
        List<StudentScoreDto> result = new ArrayList<>();
        for (Score score : scores) {
            StudentScoreDto dto = new StudentScoreDto();
            dto.setScore(score.getScore().toString());
            
            // 查询课程信息
            LambdaQueryWrapper<Course> courseWrapper = new LambdaQueryWrapper<>();
            courseWrapper.eq(Course::getNo, score.getCourseno());
            Course course = courseRepository.selectOne(courseWrapper);
            
            if (course != null) {
                dto.setNo(course.getNo());
                dto.setName(course.getName());
            } else {
                dto.setNo(score.getCourseno());
                dto.setName("未知课程");
            }
            
            result.add(dto);
        }
        
        return result;
    }
}
